package dao;

import anno.Autowired;
import anno.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import pojo.ExamRecord;
import utils.JDBCUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 考试记录DAO实现类
 */
@Component
public class ExamRecordDao extends AbstractBaseDao<ExamRecord> {

    @Autowired
    private ExamPaperDao examPaperDao;

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 根据用户ID和试卷ID查询考试记录
     *
     * @param userId  用户ID
     * @param paperId 试卷ID
     * @return 如果存在返回考试记录，否则返回 null
     */
    public ExamRecord findByUserIdAndPaperId(Integer userId, Integer paperId) throws SQLException {
        return executeWithConnection(() -> {
            String sql = String.format("SELECT * FROM %s WHERE user_id = ? AND paper_id = ?", tableName);
            ResultSet rs = (ResultSet) JDBCUtils.execute(sql, userId, paperId);
            return rs.next() ? mapResultSetToEntity(rs) : null;
        });
    }

    /**
     * 获取某个用户的所有考试记录
     *
     * @param userId 用户ID
     * @return 考试记录列表
     */
    public List<ExamRecord> findByUserId(Integer userId) throws SQLException {
        return executeWithConnection(() -> {
            String sql = String.format("SELECT * FROM %s WHERE user_id = ? ORDER BY start_time DESC", tableName);
            ResultSet rs = (ResultSet) JDBCUtils.execute(sql, userId);
            List<ExamRecord> results = new ArrayList<>();
            while (rs.next()) {
                results.add(mapResultSetToEntity(rs));
            }
            return results;
        });
    }

    /**
     * 插入考试记录
     *
     * @param record 考试记录对象
     * @return 插入后的自增主键
     */
    @Override
    public Integer insert(ExamRecord record) throws SQLException, JsonProcessingException {
        // 设置默认值，例如开始时间为当前时间
        if (record.getStartTime() == null) {
            record.setStartTime(LocalDateTime.now());
        }
        return super.insert(record);
    }

    /**
     * 更新考试记录
     *
     * @param record 考试记录对象
     * @return 是否更新成功
     */
    @Override
    public boolean update(ExamRecord record) throws SQLException, JsonProcessingException {
        return super.update(record);
    }

    /**
     * 根据ID删除考试记录
     *
     * @param recordId 记录ID
     * @return 是否删除成功
     */
    @Override
    public boolean deleteById(Integer recordId) throws SQLException {
        return super.deleteById(recordId);
    }

    /**
     * 获取所有考试记录
     *
     * @return 考试记录列表
     */
    @Override
    public List<ExamRecord> findAll() throws SQLException {
        return super.findAll();
    }

    /**
     * 根据ID查询考试记录
     *
     * @param recordId 记录ID
     * @return 考试记录对象
     */
    @Override
    public ExamRecord findById(Integer recordId) throws SQLException {
        return super.findById(recordId);
    }

    /**
     * 统计考试记录总数
     *
     * @return 总记录数
     */
    @Override
    public long count() throws SQLException {
        return super.count();
    }

    /**
     * 检查某个考试记录是否存在
     *
     * @param field 字段名
     * @param value 字段值
     * @return 是否存在
     */
    @Override
    public boolean exists(String field, Object value) throws SQLException {
        return super.exists(field, value);
    }

    /**
     * 根据指定字段查询考试记录列表
     *
     * @param field 字段名
     * @param value 字段值
     * @return 符合条件的考试记录列表
     */
    @Override
    public List<ExamRecord> findByField(String field, Object value) throws SQLException {
        return super.findByField(field, value);
    }

    /**
     * 根据指定字段查询单个考试记录
     *
     * @param field 字段名
     * @param value 字段值
     * @return 考试记录对象
     */
    @Override
    public ExamRecord findOneByField(String field, Object value) throws SQLException {
        return super.findOneByField(field, value);
    }

    /**
     * 将 ResultSet 映射为 ExamRecord 实体对象
     *
     * @param rs ResultSet
     * @return ExamRecord 实例
     */
    @Override
    protected ExamRecord mapResultSetToEntity(ResultSet rs) throws SQLException {
        try {
            ExamRecord record = new ExamRecord();
            record.setRecordId(rs.getInt("record_id"));
            record.setUserId(rs.getInt("user_id"));
            record.setPaperId(rs.getInt("paper_id"));
            record.setStartTime(rs.getTimestamp("start_time").toLocalDateTime());
            if (rs.getTimestamp("end_time") != null) {
                record.setEndTime(rs.getTimestamp("end_time").toLocalDateTime());
            }
            record.setScore(rs.getInt("score"));
            String answersJson = rs.getString("answers");
            record.setAnswers(answersJson);
            return record;
        } catch (Exception e) {
            throw new SQLException("结果集映射到实体失败", e);
        }
    }
}
